class Snake {
	// 表示蛇的元素
	head: HTMLElement
	// 蛇的身体, 包括身体
	bodies: HTMLCollection
	// 获取蛇的容器
	element: HTMLElement

	constructor() {
		this.element = document.getElementById('snake')!
		this.head = document.querySelector('#snake > div') as HTMLElement
		this.bodies = document.getElementById('snake')!.getElementsByTagName('div')
	}

	// 获取蛇的坐标	
	get X() {
		return this.head.offsetLeft
	}

	get Y() {
		return this.head.offsetTop
	}

	// 设置蛇头的坐标
	set X(value) {
		if(this.X === value) {
			return
		}
		if(value < 0 || value > 290) {  // 蛇撞墙
			throw new Error('蛇撞墙了！')
		}

		// 修改X时，判断蛇是否掉头
		if(this.bodies[1] && (this.bodies[1] as HTMLElement).offsetLeft === value) {
			// 如果掉头，使蛇向反方向继续移动
			if(value > this.X) {
				value = this.X - 10
			} else {
				value = this.X + 10
			}
		}

		// 移动身体
		this.moveBody()
		this.head.style.left = value + 'px'
		// 检查是否撞到自己
		this.checkHeadBody()
	}

	set Y(value) {
		if(this.Y === value) {
			return
		}
		if(value < 0 || value > 290) {  // 蛇撞墙
			throw new Error('蛇撞墙了！' + 'GAME OVER!')
		}

		// 修改Y时，判断蛇是否掉头
		if(this.bodies[1] && (this.bodies[1] as HTMLElement).offsetTop === value) {
			// 如果掉头，使蛇向反方向继续移动
			if(value > this.Y) {
				value = this.Y - 10
			} else {
				value = this.Y + 10
			}
		}

		// 移动身体
		this.moveBody()
		this.head.style.top = value + 'px'
		// 检查是否撞到自己
		this.checkHeadBody()
	}

	// 增加身体的方法
	addBody() {
		this.element.insertAdjacentHTML('beforeend', '<div></div>')
	}

	// 身体移动的方法
	moveBody() {
		// 第2节 = 第1节位置，以此类推
		for(let i = this.bodies.length - 1; i > 0; i--) {
			// 获取前边身体的位置, as HTMLElement类型断言
			let X = (this.bodies[i - 1] as HTMLElement).offsetLeft;
			let Y = (this.bodies[i - 1] as HTMLElement).offsetTop;

			// 讲这个值设置当前的身体
			(this.bodies[i] as HTMLElement).style.left = X + 'px';
			(this.bodies[i] as HTMLElement).style.top = Y + 'px';
		}
	}

	// 检查蛇有没有撞到自己
	checkHeadBody() {
		for(let i = 1; i < this.bodies.length; i++) {
			let bd = this.bodies[i] as HTMLElement
			if(this.X === bd.offsetLeft && this.Y === bd.offsetTop) { // 撞到身体
				throw new Error('撞到自己！' + 'GAME OVER!')
			}
		}
	}
}

export default Snake